package com.iule.common.playboy.utils;


import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;


/** JWT TOOL
 * @author 柚子
 * @date {2020/3/17}
 */
@Slf4j
public class JWTUtil {

    /**
     * 根据token和相应的token_key解析出uid
     * Decode token by key in jwt，
     * @param token token
     * @param key 验证token的key
     * @return {@code uid}
     */
    private static String getUid(String token,String key) {
        String uid = null;
        try {
            JWT.require(Algorithm.HMAC256(key)).build().verify(token);
            uid = JWT.decode(token).getAudience().get(0);
        } catch (JWTVerificationException e) {
            // 如果token 过期
            if (e instanceof TokenExpiredException){
               log.error("{}token过期{}","\033[33m","\033[0m");
            }
            if (e instanceof SignatureVerificationException) {
                log.error("{}token校验失败,推测uid可能为{}{}","\033[36m",JWT.decode(token).getAudience().get(0),"\033[0m");
            }
        }
        return uid;
    }

    /**
     * 获取uid的hash值
     * Get a hashcode of uid
     * @param uid 用户uid
     * @return {@code hashcode}
     */
    private static int getHash(String uid) {
        Assert.notNull(uid,"uid不可为空");
        return uid.hashCode() & Integer.MAX_VALUE;
    }

    ///////////////////////////////////////////////////

    /**
     * 比较hashcode  % 100 + 1的值与目标值
     * compare (hashcode mod 100 + 1） with  and target number, if they are equals,return true
     * @param hashcode  hashcode
     * @param target target Num which one less than 101
     * @return {@code compare result}
     */
    private static boolean eq(int hashcode, int target) {
        Assert.isTrue(target< 101,"目标值不可超过100");
        return hashcode % 100 +1 == target;
    }

    /**
     * 比较hashcode  % 100 + 1的值与目标值
     * compare (hashcode mod 100 + 1） with  and target number, if (hashcode mod 100 + 1） are less than target ,return true
     * @param hashcode  hashcode
     * @param target target Num which one less than 101
     * @return {@code compare result}
     */
    private static boolean lt(int hashcode, int target) {
        Assert.isTrue(target< 101,"目标值不可超过100");
        return hashcode % 100 + 1 < target;
    }

    /**
     * 比较hashcode  % 100 + 1的值与目标值
     * compare (hashcode mod 100 + 1） with  and target number, if (hashcode mod 100 + 1） are greater than target ,return true
     * @param hashcode  hashcode
     * @param target target Num which one less than 101
     * @return {@code compare result}
     */
    private static boolean gt(int hashcode, int target) {
        Assert.isTrue(target< 101,"目标值不可超过100");
        return hashcode % 100 +1 > target;
    }

    /**
     * 比较hashcode  % 100 + 1的值与目标值
     * compare (hashcode mod 100 + 1） with  and target number, if (hashcode mod 100 + 1） are less than or equals target ,return true
     * @param hashcode  hashcode
     * @param target target Num which one less than 101
     * @return {@code compare result}
     */
    private static boolean le(int hashcode, int target) {
        Assert.isTrue(target< 101,"目标值不可超过100");
        return hashcode % 100 +1 <= target;
    }

    /**
     * 比较hashcode  % 100 + 1的值与目标值
     * compare (hashcode mod 100 + 1） with  and target number, if (hashcode mod 100 + 1） are greater than target or equals target,return true
     * @param hashcode  hashcode
     * @param target target Num which one less than 101
     * @return {@code compare result}
     */
    private static boolean ge(int hashcode, int target) {
        Assert.isTrue(target< 101,"目标值不可超过100");
        return hashcode % 100 + 1 >= target;
    }

}
